/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup Web
 * @{
 *
 * @brief 提供用于拦截ArkWeb请求的API。
 * @since 12
 */
/**
 * @file arkweb_scheme_handler.h
 *
 * @brief 声明用于拦截来自ArkWeb的请求的API。
 * @sample [ArkWebSchemeHandler](https://gitee.com/openharmony/applications_app_samples/tree/master/code/DocsSample/ArkWeb/ArkWebSchemeHandler)
 * @kit ArkWeb
 * @include <web/arkweb_scheme_handler.h>
 * @library libohweb.so
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
#ifndef ARKWEB_SCHEME_HANDLER_H
#define ARKWEB_SCHEME_HANDLER_H

#include "stdint.h"

#include "arkweb_error_code.h"
#include "arkweb_net_error_list.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief custom scheme的配置信息。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
typedef enum ArkWeb_CustomSchemeOption {
    /** 表示注册自定义scheme时不赋予它任何特殊行为或能力。 */
    OH_ARKWEB_SCHEME_OPTION_NONE = 0,

    /** 如果设置了ARKWEB_SCHEME_OPTION_STANDARD，那么该scheme将被视为标准scheme来处理。
     *  标准scheme需要遵守在RFC 1738第3.1节中定义的URL规范化和解析规则，该规则可以在 http://www.ietf.org/rfc/rfc1738.txt 中找到。 */
    ARKWEB_SCHEME_OPTION_STANDARD = 1 << 0,

    /** 如果设置了ARKWEB_SCHEME_OPTION_LOCAL，则将使用与“file” URL相同的安全规则来处理该scheme。 */
    ARKWEB_SCHEME_OPTION_LOCAL = 1 << 1,

    /** 如果设置了ARKWEB_SCHEME_OPTION_DISPLAY_ISOLATED，则该scheme的请求只能由使用相同scheme加载的页面中发起。 */
    ARKWEB_SCHEME_OPTION_DISPLAY_ISOLATED = 1 << 2,

    /** 如果设置了ARKWEB_SCHEME_OPTION_SECURE，则将使用与“https” URL相同的安全规则来处理该scheme。 */
    ARKWEB_SCHEME_OPTION_SECURE = 1 << 3,

    /** 如果设置了ARKWEB_SCHEME_OPTION_CORS_ENABLED，则该scheme可以发送CORS请求。在大多数情况下，当设置了ARKWEB_SCHEME_OPTION_STANDARD时，应该设置此值。 */
    ARKWEB_SCHEME_OPTION_CORS_ENABLED = 1 << 4,

    /** 如果设置了ARKWEB_SCHEME_OPTION_CSP_BYPASSING，则该scheme可以绕过内容安全策略（CSP）检查。
     *  在大多数情况下，当设置了ARKWEB_SCHEME_OPTION_STANDARD时，不应设置此值。 */
    ARKWEB_SCHEME_OPTION_CSP_BYPASSING = 1 << 5,

    /** 如果设置了ARKWEB_SCHEME_OPTION_FETCH_ENABLED，则可以发起该scheme的FETCH API请求。 */
    ARKWEB_SCHEME_OPTION_FETCH_ENABLED = 1 << 6,

    /** 如果设置了ARKWEB_SCHEME_OPTION_CODE_CACHE_ENABLED，则该scheme的js资源支持生成code cache。 */
    ARKWEB_SCHEME_OPTION_CODE_CACHE_ENABLED = 1 << 7,
} ArkWeb_CustomSchemeOption;

/** @brief 请求的资源类型。
 *
 * 这些常量与Chromium中的ResourceType的对应项相匹配，不应重新编号。\n
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
typedef enum ArkWeb_ResourceType {
    /** 顶层页面。 */
    MAIN_FRAME = 0,

    /** Frame或Iframe。 */
    SUB_FRAME = 1,

    /** CSS样式表。 */
    STYLE_SHEET = 2,

    /** 外部脚本。 */
    SCRIPT = 3,

    /** 图片（jpg/gif/png/以及其他）。 */
    IMAGE = 4,

    /** 字体。 */
    FONT_RESOURCE = 5,

    /** 其他子资源。如果实际类型未知，则是默认类型。 */
    SUB_RESOURCE = 6,

    /** 插件的Object（或embed）标签，或者插件请求的资源。 */
    OBJECT = 7,

    /** 媒体资源。 */
    MEDIA = 8,

    /** 专用工作线程的主资源。 */
    WORKER = 9,

    /** 共享工作线程的主资源。 */
    SHARED_WORKER = 10,

    /** 明确的预取请求。 */
    PREFETCH = 11,

    /** 网站图标。 */
    FAVICON = 12,

    /** XMLHttpRequest。 */
    XHR = 13,

    /** <a ping>/sendBeacon的Ping请求。 */
    PING = 14,

    /** service worker的主资源。 */
    SERVICE_WORKER = 15,

    /** 内容安全策略违规报告。 */
    CSP_REPORT = 16,

    /** 插件请求的资源。 */
    PLUGIN_RESOURCE = 17,

    /** 触发service worker预热的主frame跳转请求。 */
    NAVIGATION_PRELOAD_MAIN_FRAME = 19,

    /** 触发service worker预热的子frame跳转请求。 */
    NAVIGATION_PRELOAD_SUB_FRAME = 20,
} ArkWeb_ResourceType;

/**
 * @brief 该类用于拦截指定scheme的请求。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
typedef struct ArkWeb_SchemeHandler_ ArkWeb_SchemeHandler;

/**
 * @brief 用于被拦截的URL请求。
 *
 * 可以通过ArkWeb_ResourceHandler发送自定义请求头以及自定义请求体。\n
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
typedef struct ArkWeb_ResourceHandler_ ArkWeb_ResourceHandler;

/**
 * @brief 为被拦截的请求构造一个ArkWeb_Response。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
typedef struct ArkWeb_Response_ ArkWeb_Response;

/**
 * @brief 对应内核的一个请求，可以通过OH_ArkWeb_ResourceRequest获取请求的URL、method、post data以及其他信息。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
typedef struct ArkWeb_ResourceRequest_ ArkWeb_ResourceRequest;

/**
 * @brief 请求头列表。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
typedef struct ArkWeb_RequestHeaderList_ ArkWeb_RequestHeaderList;

/**
 * @brief 请求的上传数据。
 *
 * 使用OH_ArkWebHttpBodyStream_*接口来读取上传的数据。\n
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
typedef struct ArkWeb_HttpBodyStream_ ArkWeb_HttpBodyStream;


/**
 * @brief 请求开始的回调，这将在IO线程上被调用。
 *
 * @param schemeHandler ArkWeb_SchemeHandler。
 * @param resourceRequest 通过该对象获取请求的信息。
 * @param resourceHandler 请求的ArkWeb_ResourceHandler。如果intercept设置为false，则不应使用它。
 * @param intercept 如果为true，则会拦截请求；如果为false，则不会拦截。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
typedef void (*ArkWeb_OnRequestStart)(const ArkWeb_SchemeHandler* schemeHandler,
                                      ArkWeb_ResourceRequest* resourceRequest,
                                      const ArkWeb_ResourceHandler* resourceHandler,
                                      bool* intercept);

/**
 * @brief 请求完成时的回调函数。
 *
 * 这将在IO线程上被调用。\n
 * 应该使用ArkWeb_ResourceRequest_Destroy销毁resourceRequest，\n
 * 并使用ArkWeb_ResourceHandler_Destroy销毁在ArkWeb_OnRequestStart中接收到的ArkWeb_ResourceHandler。\n
 *
 * @param schemeHandler ArkWeb_SchemeHandler。
 * @param resourceRequest ArkWeb_ResourceRequest。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
typedef void (*ArkWeb_OnRequestStop)(const ArkWeb_SchemeHandler* schemeHandler,
                                     const ArkWeb_ResourceRequest* resourceRequest);

/**
 * @brief 当OH_ArkWebHttpBodyStream_Read读取操作完成时的回调函数。
 * @param httpBodyStream ArkWeb_HttpBodyStream。
 * @param buffer 接收数据的buffer。
 * @param bytesRead OH_ArkWebHttpBodyStream_Read后的回调函数。如果bytesRead大于0，则表示buffer已填充了bytesRead大小的数据。
 *                  调用者可以从buffer中读取数据，如果OH_ArkWebHttpBodyStream_IsEOF为false，则调用者可以继续读取剩余的数据。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
typedef void (*ArkWeb_HttpBodyStreamReadCallback)(const ArkWeb_HttpBodyStream* httpBodyStream,
                                                  uint8_t* buffer,
                                                  int bytesRead);

/**
 * @brief 当OH_ArkWebHttpBodyStream_AsyncRead读取操作完成时的回调函数。
 * @param httpBodyStream ArkWeb_HttpBodyStream。
 * @param buffer 接收数据的缓存区。
 * @param bytesRead 标识异步读取操作执行结果的字节计数值。如果bytesRead大于0，则表示buffer已填充了bytesRead大小的数据。
 *                  开发者可以从buffer中读取数据，如果OH_ArkWebHttpBodyStream_IsEOF为false，则开发者可以继续读取剩余的数据。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 20
 */
typedef void (*ArkWeb_HttpBodyStreamAsyncReadCallback)(const ArkWeb_HttpBodyStream *httpBodyStream,
                                                       uint8_t *buffer,
                                                       int bytesRead);

/**
 * @brief  ArkWeb_HttpBodyStream初始化操作完成时回调函数。
 * @param httpBodyStream ArkWeb_HttpBodyStream。
 * @param result 成功时返回ARKWEB_NET_OK，否则请参考{@link arkweb_net_error_list.h}。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
typedef void (*ArkWeb_HttpBodyStreamInitCallback)(const ArkWeb_HttpBodyStream* httpBodyStream, ArkWeb_NetError result);

/**
 * @brief 销毁ArkWeb_RequestHeaderList对象。
 * @param requestHeaderList 将被销毁的ArkWeb_RequestHeaderList。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWebRequestHeaderList_Destroy(ArkWeb_RequestHeaderList* requestHeaderList);

/**
 * @brief 获取请求头列表的大小。
 * @param requestHeaderList 请求头的列表。
 * @return 请求头的大小。如果requestHeaderList无效，则为-1。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebRequestHeaderList_GetSize(const ArkWeb_RequestHeaderList* requestHeaderList);

/**
 * @brief 获取指定的请求头。
 * @param requestHeaderList 请求头列表。
 * @param index 请求头的索引。
 * @param key 请求头的键（key）。调用者必须使用OH_ArkWeb_ReleaseString函数来释放这个字符串。
 * @param value 请求头的值（value）。调用者必须使用OH_ArkWeb_ReleaseString函数来释放这个字符串。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWebRequestHeaderList_GetHeader(const ArkWeb_RequestHeaderList* requestHeaderList,
                                          int32_t index,
                                          char** key,
                                          char** value);

/**
 * @brief 将一个用户数据设置到ArkWeb_ResourceRequest对象中。
 * @param resourceRequest ArkWeb_ResourceRequest。
 * @param userData 将要设置的用户数据。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebResourceRequest_SetUserData(ArkWeb_ResourceRequest* resourceRequest, void* userData);

/**
 * @brief 从ArkWeb_ResourceRequest获取用户数据。
 * @param resourceRequest ArkWeb_ResourceRequest。
 * @return 设置的用户数据。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void* OH_ArkWebResourceRequest_GetUserData(const ArkWeb_ResourceRequest* resourceRequest);

/**
 * @brief 获取请求的method。
 * @param resourceRequest ArkWeb_ResourceRequest。
 * @param method HTTP请求方法。此函数将为method字符串分配内存，调用者必须使用OH_ArkWeb_ReleaseString释放字符串。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWebResourceRequest_GetMethod(const ArkWeb_ResourceRequest* resourceRequest, char** method);

/**
 * @brief 获取请求的url。
 * @param resourceRequest ArkWeb_ResourceRequest。
 * @param url 请求的URL。此函数将为URL字符串分配内存，调用者必须通过OH_ArkWeb_ReleaseString释放该字符串。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWebResourceRequest_GetUrl(const ArkWeb_ResourceRequest* resourceRequest, char** url);

/**
 * @brief 创建一个ArkWeb_HttpBodyStream，用于读取请求的上传数据。
 * @param resourceRequest ArkWeb_ResourceRequest。
 * @param httpBodyStream 请求的上传数据。此函数将为httpBodyStream分配内存，
 *                       调用者必须使用OH_ArkWebResourceRequest_DestroyHttpBodyStream释放httpBodyStream。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWebResourceRequest_GetHttpBodyStream(const ArkWeb_ResourceRequest* resourceRequest,
                                                ArkWeb_HttpBodyStream** httpBodyStream);

/**
 * @brief 销毁ArkWeb_HttpBodyStream对象。
 * @param httpBodyStream 待销毁的httpBodyStream。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWebResourceRequest_DestroyHttpBodyStream(ArkWeb_HttpBodyStream* httpBodyStream);

/**
 * @brief 获取请求的资源类型。
 * @param resourceRequest ArkWeb_ResourceRequest。
 * @return 请求的资源类型。如果resourceRequest无效，则为-1。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebResourceRequest_GetResourceType(const ArkWeb_ResourceRequest* resourceRequest);

/**
 * @brief 获取触发此请求的Frame的URL。
 * @param resourceRequest ArkWeb_ResourceRequest。
 * @param frameUrl 触发此请求的Frame的URL。此函数将为URL字符串分配内存，并且调用者必须通过OH_ArkWeb_ReleaseString来释放该字符串。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWebResourceRequest_GetFrameUrl(const ArkWeb_ResourceRequest* resourceRequest, char** frameUrl);

/**
 * @brief 将一个用户数据设置到ArkWeb_HttpBodyStream对象中。
 * @param httpBodyStream ArkWeb_HttpBodyStream。
 * @param userData 要设置的用户数据。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebHttpBodyStream_SetUserData(ArkWeb_HttpBodyStream* httpBodyStream, void* userData);

/**
 * @brief 从ArkWeb_HttpBodyStream获取用户数据。
 * @param httpBodyStream ArkWeb_HttpBodyStream。
 * @return 设置的用户数据。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void* OH_ArkWebHttpBodyStream_GetUserData(const ArkWeb_HttpBodyStream* httpBodyStream);

/**
 * @brief 为OH_ArkWebHttpBodyStream_Read设置回调函数。
 *
 * OH_ArkWebHttpBodyStream_Read的结果将通过readCallback通知给调用者。\n
 * 该回调函数将在与OH_ArkWebHttpBodyStream_Read相同的线程中运行。\n
 *
 * @param httpBodyStream ArkWeb_HttpBodyStream。
 * @param readCallback OH_ArkWebHttpBodyStream_Read的回调函数。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebHttpBodyStream_SetReadCallback(ArkWeb_HttpBodyStream* httpBodyStream,
                                                ArkWeb_HttpBodyStreamReadCallback readCallback);

/**
 * @brief 为OH_ArkWebHttpBodyStream_AsyncRead设置回调函数。
 *
 * OH_ArkWebHttpBodyStream_AsyncRead的结果将通过readCallback通知给开发者。\n
 * 该回调函数会在ArkWeb工作线程中运行。\n
 *
 * @param httpBodyStream ArkWeb_HttpBodyStream。
 * @param readCallback OH_ArkWebHttpBodyStream_AsyncRead的回调函数。
 * @return 返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 20
 */
int32_t OH_ArkWebHttpBodyStream_SetAsyncReadCallback(ArkWeb_HttpBodyStream *httpBodyStream,
                                                     ArkWeb_HttpBodyStreamAsyncReadCallback readCallback);

/**
 * @brief 初始化ArkWeb_HttpBodyStream。
 *
 * 在调用任何其他函数之前，必须调用此函数。该接口需要在IO线程调用。\n
 *
 * @param httpBodyStream ArkWeb_HttpBodyStream。
 * @param initCallback 初始化的回调函数。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebHttpBodyStream_Init(ArkWeb_HttpBodyStream* httpBodyStream,
                                     ArkWeb_HttpBodyStreamInitCallback initCallback);

/**
 * @brief 将请求的上传数据读取到buffer。
 *
 * buffer的大小必须大于bufLen。我们将从工作线程读取数据到buffer，因此在回调函数返回之前，不应在其他线程中使用buffer，以避免并发问题。\n
 *
 * @param httpBodyStream ArkWeb_HttpBodyStream。
 * @param buffer 接收数据的buffer。
 * @param bufLen 要读取的字节的大小。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWebHttpBodyStream_Read(const ArkWeb_HttpBodyStream* httpBodyStream, uint8_t* buffer, int bufLen);

/**
 * @brief 将请求的上传数据读取到buffer。
 *
 * buffer的大小必须大于bufLen。数据将从工作线程读取数据到buffer，因此在回调函数返回之前，不应在其他线程中使用buffer，以避免并发问题。\n
 *
 * @param httpBodyStream ArkWeb_HttpBodyStream。
 * @param buffer 接收数据的缓存区。
 * @param bufLen 要读取的字节的大小。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 20
 */
void OH_ArkWebHttpBodyStream_AsyncRead(const ArkWeb_HttpBodyStream *httpBodyStream, uint8_t *buffer, int bufLen);

/**
 * @brief 获取httpBodyStream的大小。
 *
 * 当数据以分块的形式传输或httpBodyStream无效时，始终返回0。\n
 *
 * @param httpBodyStream ArkWeb_HttpBodyStream。
 * @return httpBodyStream的大小。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
uint64_t OH_ArkWebHttpBodyStream_GetSize(const ArkWeb_HttpBodyStream* httpBodyStream);

/**
 * @brief 获取httpBodyStream当前的读取位置。
 * @param httpBodyStream ArkWeb_HttpBodyStream。
 * @return httpBodyStream当前的读取位置。如果httpBodyStream无效，则位置为0。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
uint64_t OH_ArkWebHttpBodyStream_GetPosition(const ArkWeb_HttpBodyStream* httpBodyStream);

/**
 * @brief 获取httpBodyStream是否采用分块传输。
 * @param httpBodyStream ArkWeb_HttpBodyStream。
 * @return 如果采用分块传输则返回true;否则返回false。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
bool OH_ArkWebHttpBodyStream_IsChunked(const ArkWeb_HttpBodyStream* httpBodyStream);


/**
 * @brief 如果httpBodyStream中的所有数据都已被读取，则返回true。
 *
 * 对于分块传输类型的httpBodyStream，在第一次读取尝试之前返回false。\n
 *
 * @param httpBodyStream ArkWeb_HttpBodyStream。
 * @return 如果所有数据都已被读取则返回true；否则返回false。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
bool OH_ArkWebHttpBodyStream_IsEof(const ArkWeb_HttpBodyStream* httpBodyStream);

/**
 * @brief 如果httpBodyStream中的上传数据完全在内存中，并且所有读取请求都将同步成功，则返回true。
 *
 * 对于分块传输类型的数据，预期返回false。\n
 *
 * @param httpBodyStream ArkWeb_HttpBodyStream。
 * @return 如果上传数据完全在内存中则返回true；否则返回false。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
bool OH_ArkWebHttpBodyStream_IsInMemory(const ArkWeb_HttpBodyStream* httpBodyStream);

/**
 * @brief 销毁ArkWeb_ResourceRequest对象。
 * @param resourceRequest ArkWeb_ResourceRequest。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebResourceRequest_Destroy(const ArkWeb_ResourceRequest* resourceRequest);

/**
 * @brief 获取请求的Referrer。
 * @param resourceRequest ArkWeb_ResourceRequest。
 * @param referrer 请求的Referrer。此函数将为referrer字符串分配内存，调用者必须使用 OH_ArkWeb_ReleaseString 释放该字符串。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWebResourceRequest_GetReferrer(const ArkWeb_ResourceRequest* resourceRequest, char** referrer);

/**
 * @brief 获取请求的请求头列表OH_ArkWeb_RequestHeaderList。
 * @param resourceRequest ArkWeb_ResourceRequest。
 * @param requestHeaderList 请求的请求头列表。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWebResourceRequest_GetRequestHeaders(const ArkWeb_ResourceRequest* resourceRequest,
                                                ArkWeb_RequestHeaderList** requestHeaderList);

/**
 * @brief 判断这是否是一个重定向请求。
 * @param resourceRequest ArkWeb_ResourceRequest。
 * @return 如果这是一个重定向，则返回true；否则返回false。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
bool OH_ArkWebResourceRequest_IsRedirect(const ArkWeb_ResourceRequest* resourceRequest);

/**
 * @brief 判断这是否是主框架文档资源的请求。
 * @param resourceRequest ArkWeb_ResourceRequest。
 * @return 如果这是来自主框架，则返回true；否则返回false。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
bool OH_ArkWebResourceRequest_IsMainFrame(const ArkWeb_ResourceRequest* resourceRequest);

/**
 * @brief 判断这是否是一个由用户手势触发的请求。
 * @param resourceRequest ArkWeb_ResourceRequest。
 * @return 如果这是由用户手势触发的，则返回true；否则返回false。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
bool OH_ArkWebResourceRequest_HasGesture(const ArkWeb_ResourceRequest* resourceRequest);

/**
 * @brief 将custom scheme注册到ArkWeb。
 *
 * 对于内置的HTTP、HTTPS、FILE、FTP、ABOUT和DATA协议，不应调用此函数。\n
 * 此函数应在主线程上调用并且需要在内核初始化之前调用。\n
 *
 * @param scheme 待注册的scheme。
 * @param option scheme的配置（行为）。
 * @return 如果返回0，表示成功；返回17100100，表示未知错误；返回17100101，表示参数无效；返回17100102，表示注册scheme的配置失败，应该在创建ArkWeb之前注册。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWeb_RegisterCustomSchemes(const char* scheme, int32_t option);

/**
 * @brief 为指定scheme设置一个ArkWeb_SchemeHandler以拦截ServiceWorker触发的该scheme类型的请求。
 *
 * 应该在创建BrowserContext之后设置SchemeHandler。\n
 * 可以使用WebviewController.initializeWebEngine来初始化BrowserContext而无需创建ArkWeb。\n
 *
 * @param scheme 需要被拦截的scheme。
 * @param schemeHandler 该scheme的拦截器ArkWeb_SchemeHandler。只有通过ServiceWorker触发的请求才会通过这个schemeHandler进行通知。
 * @return 如果为指定scheme设置SchemeHandler成功，则返回true，否则返回false。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
bool OH_ArkWebServiceWorker_SetSchemeHandler(const char* scheme, ArkWeb_SchemeHandler* schemeHandler);

/**
 * @brief 为指定scheme设置一个ArkWeb_SchemeHandler以拦截该scheme类型的请求。
 *
 * 应该在创建BrowserContext之后设置SchemeHandler。\n
 * 可以使用WebviewController.initializeWebEngine来初始化BrowserContext而无需创建ArkWeb。\n
 *
 * @param scheme 需要被拦截的scheme。
 * @param webTag Web组件的标签名称，用于标识某个唯一组件，由开发者来保证名称唯一性。
 * @param schemeHandler 该scheme的拦截器ArkWeb_SchemeHandler。只有从指定web触发的请求才会通过这个schemeHandler进行通知。
 * @return 如果为指定scheme设置SchemeHandler成功，则返回true，否则返回false。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
bool OH_ArkWeb_SetSchemeHandler(const char* scheme, const char* webTag, ArkWeb_SchemeHandler* schemeHandler);

/**
 * @brief 清除为ServiceWorker注册的SchemeHandler。
 * @return 如果返回0，表示成功。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebServiceWorker_ClearSchemeHandlers();

/**
 * @brief 清除为指定web注册的SchemeHandler。
 * @param webTag Web组件的标签名称，用于标识某个唯一组件，由开发者来保证名称唯一性。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWeb_ClearSchemeHandlers(const char* webTag);

/**
 * @brief 创建一个ArkWeb_SchemeHandler对象。
 * @param schemeHandler 返回创建的ArkWeb_SchemeHandler。在不需要时使用OH_ArkWeb_DestoryschemeHandler销毁它。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWeb_CreateSchemeHandler(ArkWeb_SchemeHandler** schemeHandler);

/**
 * @brief 销毁一个ArkWeb_SchemeHandler对象。
 * @param schemeHandler 待销毁的ArkWeb_SchemeHandler。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWeb_DestroySchemeHandler(ArkWeb_SchemeHandler* schemeHandler);

/**
 * @brief 将一个用户数据设置到ArkWeb_SchemeHandler对象中。
 * @param schemeHandler ArkWeb_SchemeHandler。
 * @param userData 要设置的用户数据。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebSchemeHandler_SetUserData(ArkWeb_SchemeHandler* schemeHandler, void* userData);

/**
 * @brief 从ArkWeb_SchemeHandler获取用户数据。
 * @param schemeHandler ArkWeb_SchemeHandler。
 * @return 设置的用户数据。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void* OH_ArkWebSchemeHandler_GetUserData(const ArkWeb_SchemeHandler* schemeHandler);

/**
 * @brief 为SchemeHandler设置OnRequestStart回调。
 * @param schemeHandler 该scheme的SchemeHandler。
 * @param onRequestStart OnRequestStart回调函数。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebSchemeHandler_SetOnRequestStart(ArkWeb_SchemeHandler* schemeHandler,
                                                 ArkWeb_OnRequestStart onRequestStart);

/**
 * @brief 为SchemeHandler设置OnRequestStop回调。
 * @param schemeHandler 该scheme的SchemeHandler。
 * @param onRequestStop OnRequestStop回调函数。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebSchemeHandler_SetOnRequestStop(ArkWeb_SchemeHandler* schemeHandler,
                                                ArkWeb_OnRequestStop onRequestStop);

/**
 * @brief 为被拦截的请求创建一个ArkWeb_Response对象。
 * @param response 返回创建的ArkWeb_Response。在不需要时使用OH_ArkWeb_DestoryResponse进行销毁。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWeb_CreateResponse(ArkWeb_Response** response);

/**
 * @brief 销毁一个ArkWeb_Response对象。
 * @param response 待销毁的ArkWeb_Response。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWeb_DestroyResponse(ArkWeb_Response* response);

/**
 * @brief 设置经过重定向或由于HSTS而改变后的解析URL，设置后会触发跳转。
 * @param response ArkWeb_Response。
 * @param url 解析后的URL。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebResponse_SetUrl(ArkWeb_Response* response, const char* url);

/**
 * @brief 获取经过重定向或由于HSTS而更改后的解析URL。
 * @param response ArkWeb_Response。
 * @param url 解析后的URL。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWebResponse_GetUrl(const ArkWeb_Response* response, char** url);

/**
 * @brief 给ArkWeb_Response对象设置一个错误码。
 * @param response ArkWeb_Response。
 * @param errorCode 失败请求的错误码。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebResponse_SetError(ArkWeb_Response* response, ArkWeb_NetError errorCode);

/**
 * @brief 获取ArkWeb_Response的错误码。
 * @param response ArkWeb_Response。
 * @return ArkWeb_Response的错误码。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
ArkWeb_NetError OH_ArkWebResponse_GetError(const ArkWeb_Response* response);

/**
 * @brief 为ArkWeb_Response对象设置一个HTTP状态码。
 * @param response ArkWeb_Response。
 * @param status 请求的HTTP状态码。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebResponse_SetStatus(ArkWeb_Response* response, int status);

/**
 * @brief 获取ArkWeb_Response的HTTP状态码。
 * @param response ArkWeb_Response。
 * @return ArkWeb_Response的HTTP状态码。如果ArkWeb_Response无效，则为-1。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int OH_ArkWebResponse_GetStatus(const ArkWeb_Response* response);

/**
 * @brief 为ArkWeb_Response设置状态文本。
 * @param response ArkWeb_Response。
 * @param statusText 请求的状态文本。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebResponse_SetStatusText(ArkWeb_Response* response, const char* statusText);

/**
 * @brief 获取ArkWeb_Response的状态文本。
 * @param response ArkWeb_Response。
 * @param statusText 返回ArkWeb_Response的状态文本。此函数将为statusText字符串分配内存，调用方必须通过OH_ArkWeb_ReleaseString释放该字符串。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWebResponse_GetStatusText(const ArkWeb_Response* response, char** statusText);

/**
 * @brief 为ArkWeb_Response设置媒体类型。
 * @param response ArkWeb_Response。
 * @param mimeType 请求的媒体类型。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebResponse_SetMimeType(ArkWeb_Response* response, const char* mimeType);

/**
 * @brief 获取ArkWeb_Response的媒体类型。
 * @param response ArkWeb_Response。
 * @param mimeType 返回ArkWeb_Response的媒体类型。此函数将为mimeType字符串分配内存，调用方必须通过OH_ArkWeb_ReleaseString释放该字符串。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWebResponse_GetMimeType(const ArkWeb_Response* response, char** mimeType);

/**
 * @brief 为ArkWeb_Response设置字符集。
 * @param response ArkWeb_Response。
 * @param charset 请求的字符集。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebResponse_SetCharset(ArkWeb_Response* response, const char* charset);

/**
 * @brief 获取ArkWeb_Response的字符集。
 * @param response ArkWeb_Response。
 * @param charset 返回ArkWeb_Response的字符集。此函数将为charset字符串分配内存，调用方必须通过OH_ArkWeb_ReleaseString释放字符串。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWebResponse_GetCharset(const ArkWeb_Response* response, char** charset);

/**
 * @brief 为ArkWeb_Response设置一个header。
 * @param response ArkWeb_Response。
 * @param name header的名称。
 * @param value header的值。
 * @param overwirte 如果为true，将覆盖现有的header，否则不覆盖。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebResponse_SetHeaderByName(ArkWeb_Response* response,
                                          const char* name,
                                          const char* value,
                                          bool overwrite);

/**
 * @brief 从ArkWeb_Response中获取header。
 * @param response ArkWeb_Response。
 * @param name header的名称。
 * @param value 返回header的值。此函数将为value字符串分配内存，调用方必须通过OH_ArkWeb_ReleaseString释放该字符串。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWebResponse_GetHeaderByName(const ArkWeb_Response* response, const char* name, char** value);

/**
 * @brief 销毁一个ArkWeb_ResourceHandler对象。
 * @param resourceHandler ArkWeb_ResourceHandler。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebResourceHandler_Destroy(const ArkWeb_ResourceHandler* resourceHandler);

/**
 * @brief 将构造的响应头传递给被拦截的请求。
 * @param resourceHandler 该请求的ArkWeb_ResourceHandler。
 * @param response 该拦截请求的ArkWeb_Response。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebResourceHandler_DidReceiveResponse(const ArkWeb_ResourceHandler* resourceHandler,
                                                    const ArkWeb_Response* response);

/**
 * @brief 将构造的响应体传递给被拦截的请求。
 * @param resourceHandler 该请求的ArkWeb_ResourceHandler。
 * @param buffer 要发送的buffer数据。
 * @param bufLen buffer的大小。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebResourceHandler_DidReceiveData(const ArkWeb_ResourceHandler* resourceHandler,
                                                const uint8_t* buffer,
                                                int64_t bufLen);

/**
 * @brief 通知ArkWeb内核被拦截的请求已经完成，并且没有更多的数据可用。
 * @param resourceHandler 该请求的ArkWeb_ResourceHandler。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebResourceHandler_DidFinish(const ArkWeb_ResourceHandler* resourceHandler);

/**
 * @brief 通知ArkWeb内核被拦截请求应该失败。
 * @param resourceHandler 该请求的ArkWeb_ResourceHandler。
 * @param errorCode 该请求的错误码。请参考{@link arkweb_net_error_list.h}。
 * @return 如果返回0，表示成功；返回17100101，表示参数无效。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
int32_t OH_ArkWebResourceHandler_DidFailWithError(const ArkWeb_ResourceHandler* resourceHandler,
                                                  ArkWeb_NetError errorCode);

/**
 * @brief 释放由NDK接口创建的字符串。
 * @param string 待释放的字符串。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWeb_ReleaseString(char* string);

/**
 * @brief 释放由NDK接口创建的字节数组。
 * @param byteArray 待释放的字节数组。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 12
 */
void OH_ArkWeb_ReleaseByteArray(uint8_t* byteArray);


#ifdef __cplusplus
};
#endif
#endif // ARKWEB_SCHEME_HANDLER_H
